#!/usr/bin/env python


# Copyright (c) 2011 by Kenneth Dixon
#
# GNU General Public Licence (GPL)
# 
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA  02111-1307  USA
#

import asyncore
import socket
import re #regex 
import Properties as pr#My properties file
import daemon
import logging
import Email
import IPCam

class X10Controller(asyncore.dispatcher):
    
    def __init__(self, host, port):
        self.init_logger()
        self.logger.info("Creating the connection to the CM15 device")
        
        asyncore.dispatcher.__init__(self)
        
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect( (host, port) )
        
        self.logger.info("Initialising buffer variable with empty string")
        self.buffer = ""
        
        self.logger.info("Initialising Email")
        self.myEmail = Email.Email()
        
        self.logger.info("Initialising IP Camera")
        self.myIPCam = IPCam.IPCam()



    def init_logger(self):
        self.logger = logging.getLogger(pr.LOGGER_NAME)
        
        fh = logging.FileHandler(pr.WORKING_DIR+pr.LOG_FILE_NAME)
        fh.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
        fh.setFormatter(formatter)
        self.logger.addHandler(fh)
        
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        self.logger.addHandler(ch)
        
        self.logger.setLevel(logging.DEBUG)
        self.logger.info("Logger initialised")
    
    def handle_connect(self):
        self.logger.info("Connected")

    def handle_close(self):
        self.close()

    def handle_read(self):
        incomingCommand = self.recv(1024)
        self.logger.info("Incomming Command: "+incomingCommand)
        
        if (re.search(pr.REC_PREFIX+pr.REC_MOTION_SENSOR_1+pr.REC_POSTFIX_ON,incomingCommand)) or (re.search(pr.REC_PREFIX+pr.REC_MOTION_SENSOR_2+pr.REC_POSTFIX_ON,incomingCommand)):
            self.logger.info("Motion Detected")
            if pr.isDark:
                self.logger.info("It's dark and 'ON' Monitor command recieved, sending 'ON' command to Lights")
                self.buffer = pr.SEND_PREFIX+pr.SEND_LIGHT_1+pr.SEND_POSTFIX_ON
                self.buffer = pr.SEND_PREFIX+pr.SEND_LIGHT_2+pr.SEND_POSTFIX_ON   
            else:
                self.logger.info("It's already light so don't turn on light")
            #After lights on, or daylight
            self.logger.info("Triggering Snapshots")
            snapshotDir = self.myIPCam.getSnapshots()
            self.logger.info("Triggering Send Email")
            self.myEmail.sendSnapshotEmail(snapshotDir)
        elif (re.search(pr.REC_PREFIX+pr.REC_MOTION_SENSOR_1+pr.REC_POSTFIX_OFF,incomingCommand)) or (re.search(pr.REC_PREFIX+pr.REC_MOTION_SENSOR_2+pr.REC_POSTFIX_OFF,incomingCommand)):
            self.logger.info("'OFF' Monitor command recieved, sending 'OFF' command to Lights")
            self.buffer = pr.SEND_PREFIX+pr.SEND_LIGHT_1+pr.SEND_POSTFIX_OFF
            self.buffer = pr.SEND_PREFIX+pr.SEND_LIGHT_2+pr.SEND_POSTFIX_OFF
        elif (re.search(pr.REC_PREFIX+pr.REC_LIGHT_SENSOR_1+pr.REC_POSTFIX_ON,incomingCommand)) or (re.search(pr.REC_PREFIX+pr.REC_LIGHT_SENSOR_2+pr.REC_POSTFIX_ON,incomingCommand)):
            pr.isDark = True
        elif (re.search(pr.REC_PREFIX+pr.REC_LIGHT_SENSOR_1+pr.REC_POSTFIX_OFF,incomingCommand)) or (re.search(pr.REC_PREFIX+pr.REC_LIGHT_SENSOR_2+pr.REC_POSTFIX_OFF,incomingCommand)):
            pr.isDark = False
        else:
            self.logger.warning("Unrecognised incomming Command: "+incomingCommand)

    def writable(self):
        
        if(len(self.buffer) > 0):
            self.logger.info("Buffer contains command...will now send")
            return True
        else:
            self.logger.info("No command in buffer...do nothing")
            return False


    def handle_write(self):
        self.logger.info("Sending command to CM15 device: "+self.buffer)
        sent = self.send(self.buffer)
        self.logger.info("Emptying the buffer so the command is not sent multiple times")
        self.buffer = self.buffer[sent:]

def main():
    client = X10Controller(pr.HOST, pr.PORT)
    asyncore.loop()

#Run as daemon
with daemon.DaemonContext(working_directory=pr.WORKING_DIR):
    main()
    
